{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "移动到 PPDiffusersWebUI 同级目录才有效"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h1><span style=\"background: linear-gradient(to right, red, orange, yellow, green, blue, indigo, violet);  -webkit-background-clip: text;  -webkit-text-fill-color: transparent;\">Animagine-XL3.1</span></h1>\n",
    "\n",
    "\n",
    "**单模型safetensors权重转换pd权重**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 准备工作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "# 解压转换工具\n",
    "!unzip data/data268105/convertkeys.zip"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "# 环境准备\n",
    "evn='''\n",
    "ppdiffusers==0.24.0 \n",
    "paddlenlp==2.7.2 \n",
    "'''\n",
    "with open(\"requirements.txt\", \"w\", encoding=\"utf-8\") as fp:\n",
    "    fp.writelines(evn)\n",
    "\n",
    "import os\n",
    "os.makedirs(\"~/external-libraries\", exist_ok=True)\n",
    "os.system(\"pip install -r requirements.txt -t ~/external-libraries\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模型转换"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Animagine-xl-3.1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "# 单文件权重转换safetensor，--model_name [待转换模型路径]\n",
    "!python convertkeys/convert_key.py \\\n",
    "    --model_name data/data268105/animagine-xl-3.1.safetensors"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Pony-v6-XL"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "# 单文件权重转换safetensor，--model_name [待转换模型路径]\n",
    "!python convertkeys/convert_key.py \\\n",
    "    --model_name data/data270713/ponyDiffusionV6XL_v6TurboDPOMerge.safetensors\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "# 单文件权重转换safetensor，--model_name [待转换模型路径]\n",
    "!python convertkeys/convert_key.py \\\n",
    "    --model_name data/data270713/pony_pencil-XL-v1.0.2.safetensors\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模型测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "import warnings  \n",
    "warnings.filterwarnings(\"ignore\")\n",
    "# 模型测试\n",
    "import sys\n",
    "sys.path.append('/home/aistudio/external-libraries')\n",
    "\n",
    "import paddle\n",
    "from ppdiffusers import StableDiffusionXLPipeline\n",
    "import time, os\n",
    "from PIL import PngImagePlugin  \n",
    "\n",
    "\n",
    "HOME_DIR = os.path.expanduser('~') \n",
    "\n",
    "def custom_save_image(image, metadata, root, model_dir, *args):\n",
    "    output_dir = f\"{root}/{model_dir.split('/')[-1]}\"\n",
    "    os.makedirs(output_dir, exist_ok=True)\n",
    "\n",
    "    extra = ('_'.join(args) + '_') if args else ''\n",
    "    filename = f\"{extra}{time.strftime('%Y%m%d_%H%M%S', time.localtime())}.png\"\n",
    "    outpath = os.path.join(output_dir, filename)\n",
    "\n",
    "    # 创建PngInfo对象  \n",
    "    png_info = PngImagePlugin.PngInfo()  \n",
    "    # 添加文本元数据  \n",
    "    for key, value in metadata.items():  \n",
    "        if not isinstance(value, str):\n",
    "            value = str(value)\n",
    "        png_info.add_text(key, value)\n",
    "    image.save(outpath, 'PNG', pnginfo=png_info)\n",
    "\n",
    "model_dir = [\n",
    "    \"Animagine-Xl-3.1\", \n",
    "    \"Pony_Pencil-Xl-V1.0.2\", \n",
    "    \"Ponydiffusionv6Xl_V6Turbodpomerge\",\n",
    "][-3]\n",
    "\n",
    "pipe = StableDiffusionXLPipeline.from_pretrained(\n",
    "    model_dir, \n",
    "    paddle_dtype=paddle.float16\n",
    ")\n",
    "pipe.enable_xformers_memory_efficient_attention()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "from ppdiffusers import EulerDiscreteScheduler, DDPMScheduler, EulerAncestralDiscreteScheduler\n",
    "# pipe.scheduler = DDPMScheduler.from_config(pipe.scheduler.config)\n",
    "# pipe.scheduler = EulerDiscreteScheduler.from_config(pipe.scheduler.config)\n",
    "pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)\n",
    "print(\n",
    "\"\"\"\n",
    "推荐尺寸：\n",
    "768 x 1344: Vertical (9:16)\n",
    "912 x 1144: Portrait (4:5)\n",
    "1024 x 1024: Square (1:1)\n",
    "1184 x 888: Photo (4:3)\n",
    "1256 x 840: Landscape (3:2)\n",
    "1368 x 768: Widescreen (16:9)\n",
    "1568 x 672: Cinematic (21:9)\n",
    "\"\"\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "# 游戏名\n",
    "games = [\n",
    "    \"GenShion Impact\",\n",
    "    \"neon genesis evangelion\",\n",
    "][0]\n",
    "# 角色名\n",
    "rolers = [\n",
    "    \"Sangonomiya Kokomi\",\n",
    "    \"KeQing\",\n",
    "    \"souryuu asuka langley\"\n",
    "][0]\n",
    "roler_scale = 1.0\n",
    "# 服装\n",
    "clothes = [\n",
    "    \"Sun Dress\",\n",
    "    \"bikini\"\n",
    "][1]\n",
    "cloth_scale = 1.0\n",
    "# 颜色\n",
    "color = [\n",
    "    \"yellow\"\n",
    "][0]\n",
    "color_scale = 1.1\n",
    "# 脖子装饰\n",
    "necklace = [\n",
    "    \"\",\n",
    "    \"necklace, turtleneck\",\n",
    "][0]\n",
    "prompt = f\"{games} roler {rolers}:{roler_scale}, solo, slim, perfect face, look at viewer, standing, bangs, single hair bun, long hair, grey eyes, parted lips, \" \\\n",
    "    f\"jewelry, off-shoulders, {color}:{color_scale}, {clothes}:{cloth_scale}, {necklace}, masterpiece, best quality, highly detailed\"\n",
    "negative_prompt = \"nsfw, lowres, (bad), multy girls, text, extra fingers, error, fewer, extra, missing, worst quality, jpeg artifacts, low quality, watermark, unfinished, displeasing, oldest, early, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]\"\n",
    "\n",
    "image = pipe(\n",
    "    prompt, \n",
    "    negative_prompt=negative_prompt,\n",
    "    width=768,\n",
    "    height=1344, \n",
    "    guidance_scale=7,\n",
    "    num_inference_steps=20, \n",
    "    target_size=(1024,1024),\n",
    "    original_size=(4096,4096),\n",
    "    # generator=paddle.Generator().manual_seed(42)\n",
    ").images[0]\n",
    "paddle.device.cuda.empty_cache()\n",
    "\n",
    "metadata = {  \n",
    "    'Title': 'Test Image Title',  \n",
    "    'Author': 'Covirtue'  \n",
    "} \n",
    "root = HOME_DIR + '/out_puts'\n",
    "custom_save_imgae(\n",
    "    image, \n",
    "    metadata, \n",
    "    root, \n",
    "    model_dir, \n",
    "    games, \n",
    "    rolers,\n",
    ")\n",
    "image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-19T03:33:19.972548Z",
     "iopub.status.busy": "2024-05-19T03:33:19.971804Z",
     "iopub.status.idle": "2024-05-19T03:33:19.979741Z",
     "shell.execute_reply": "2024-05-19T03:33:19.979014Z",
     "shell.execute_reply.started": "2024-05-19T03:33:19.972506Z"
    },
    "scrolled": true,
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'/home/aistudio/Animagine-Xl-3.1'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from PPDiffusersWebUI.utils.check_image import check_image_infos\n",
    "image_path_or_file = \"NingGuang_20240519_105243.png\"\n",
    "check_image_infos(image_path_or_file)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "# !git clone https://gitee.com/Covirtue/PPDiffusersWebUI.git\n",
    "!pip install -r requirements.txt --user"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "# web测试\n",
    "from PPDiffusersWebUI.utils.webui_func import LoadTypesModel\n",
    "\n",
    "re = LoadTypesModel().mix2img(\n",
    "    \"/home/aistudio/Animagine-Xl-3.1\",\n",
    "    \"girl\",\n",
    "    \"\",\n",
    "    num_inference_steps=30\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "# web测试\n",
    "from PPDiffusersWebUI.utils.webui_func import LoadTypesModel\n",
    "# 初始化模型\n",
    "load_model = None\n",
    "\n",
    "# 文生图函数\n",
    "def text2img(\n",
    "    pipe,\n",
    "    prompt,\n",
    "    negative_prompt,\n",
    "    guidance_scale=5,\n",
    "    height=1024,\n",
    "    width=1024,\n",
    "    num_inference_steps=30,\n",
    "    seed=-1,\n",
    "    num_images_per_prompt=1,\n",
    "    scheduler_type='ddpm',\n",
    "    model_name_input=None,\n",
    "    enable_xformers=\"ON\", \n",
    "    vae_dir=\"\", \n",
    "    vae_dir_input=\"\", \n",
    "    max_size=1900, \n",
    "    rolers=\"KeqQing\", \n",
    "    load_to_cpu=\"OFF\",\n",
    "    type_to_img=\"text\", \n",
    "    **kwargs\n",
    "):  \n",
    "    pipe = model_name_input or pipe\n",
    "    vae_dir = vae_dir_input or vae_dir\n",
    "    vae_dir = vae_dir if vae_dir else (pipe + '/vae')\n",
    "    # 如果模型改变则重新加载模型\n",
    "    global load_model \n",
    "    if not load_model:\n",
    "        load_model = LoadTypesModel(pipe, vae_dir=vae_dir) \n",
    "        load_model.type_to_img = \"text\"\n",
    "        load_model.scheduler_type = \"default\"\n",
    "    if load_model.pipe != pipe or load_model.vae_dir != vae_dir: \n",
    "        load_model = LoadTypesModel(pipe, vae_dir=vae_dir) \n",
    "        if pipe not in model_list:\n",
    "            model_list.append(pipe)    \n",
    "            \n",
    "    return load_model.mix2img(\n",
    "        pipe,\n",
    "        prompt,\n",
    "        negative_prompt,\n",
    "        guidance_scale=guidance_scale,\n",
    "        height=height,\n",
    "        width=width,\n",
    "        num_inference_steps=num_inference_steps,\n",
    "        num_images_per_prompt=num_images_per_prompt,\n",
    "        scheduler_type=scheduler_type,\n",
    "        seed=seed,\n",
    "        enable_xformers=enable_xformers, \n",
    "        type_to_img=type_to_img,\n",
    "        model_name_input=model_name_input, \n",
    "        max_size=max_size, \n",
    "        rolers=rolers, \n",
    "    ) + (json.dumps(model_list),) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "import json, time\n",
    "start = time.time()\n",
    "model_list = [\n",
    "    'SG161222/RealVisXL_V3.0',\n",
    "    '/Animagine-Xl-2.0',\n",
    "    '/Animagine-Xl-3.1',\n",
    "]\n",
    "re = text2img(\n",
    "    \"/home/aistudio/Animagine-Xl-3.1\",\n",
    "    # 'SG161222/RealVisXL_V3.0',\n",
    "    \"girl\",\n",
    "    \"\",\n",
    "    num_inference_steps=30\n",
    ")\n",
    "end = time.time()\n",
    "print(end-start)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "load_model.type_to_img"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "py35-paddle1.2.0"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.10"
  },
  "toc-autonumbering": true
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
